﻿/*
 * This file is part of quickReminder, a software for gamers
 *
 * Copyright (C) 2006-2009 Lucas Romero
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Xml.Serialization;

namespace LucasCode.PublicTypes
{
    [Serializable]
    public class MatchPlayer : IComparable
    {
        public override bool Equals(object obj)
        {
            return (CompareTo(obj) == 0);
        }

        public int CompareTo(object b)
        {
            MatchPlayer p = (MatchPlayer)b, player = this;
            if (Equals(p.CurrentNick, p.UserID, p.GameID) || p.GameAccountList.Contains(player.GameID))
                return 0;
            return -1;
        }

        public bool Equals(string name, string userID, string gameID)
        {
            if ((!string.IsNullOrEmpty(UserID) && userID == UserID) || (!string.IsNullOrEmpty(GameID) && gameID == GameID) || GameAccountList.Contains(gameID) || name == CurrentNick)
            {
                return true;
            }
            return false;
        }

        #region Private Properties
        private string m_GameID = string.Empty;
        private string m_UserID = string.Empty;
        private string m_ESLNick = string.Empty;
        private string m_CurrentNick = string.Empty;
        private int m_qrID;
        private bool m_IsArchiveOwner;
        private bool m_IsBarred;
        private bool m_HasAequitasLog;

        private GameAccountCollection m_GameAccounts = new GameAccountCollection();
        private StringCollection m_Names = new StringCollection();
        private List<MatchAction> m_Actions = new List<MatchAction>();
        private MatchContestant m_Team;
        #endregion

        #region Constructors
        public MatchPlayer()
        {
            m_qrID = QuickReminderID.LowestID;
            QuickReminderID.IncreaseID();
        }

        public MatchPlayer(string name)
        {
            m_CurrentNick = name;

            m_qrID = QuickReminderID.LowestID;
            QuickReminderID.IncreaseID();

            m_Names.Add(name);
        }
        #endregion

        #region Properties
        public bool HasAequitasLog
        {
            get { return m_HasAequitasLog; }
            set { m_HasAequitasLog = value; }
        }

        public string CurrentNick
        {
            get { return m_CurrentNick; }
            set
            {
                m_CurrentNick = value;
                if (!m_GameAccounts.Contains(value))
                    m_GameAccounts.Add(new GameAccount("undefined", value));
            }
        }

        public string[] Names
        {
            get
            {
                var names = new string[m_Names.Count];
                m_Names.CopyTo(names, 0);
                return names;
            }
            set
            {
                m_Names.Clear();
                m_Names.AddRange(value);
            }
        }
        //TODO: change this to uint
        public string UserID
        {
            get { return m_UserID; }
            set { m_UserID = value; }
        }

        public string ESLNick
        {
            get { return m_ESLNick; }
            set { m_ESLNick = value; }
        }

        //?? Sinn von GameID wenn UserID schon da is?
        public string GameID
        {
            get { return m_GameID; }
            set { m_GameID = value;
            if (!m_Names.Contains(value))
                m_Names.Add(value);
            }
        }

        public int QrID
        {
            get { return m_qrID; }
            set { m_qrID = value; }
        }

        public MatchAction[] Actions
        {
            get { return m_Actions.ToArray(); }
            set
            {
                m_Actions.Clear();
                m_Actions.AddRange(value);
            }
        }

        public bool IsArchiveOwner
        {
            get { return m_IsArchiveOwner; }
            set { m_IsArchiveOwner = value; }
        }

        public bool IsBarred
        {
            get { return m_IsBarred; }
            set { m_IsBarred = value; }
        }

        public GameAccount[] GameAccounts
        {
            get { return m_GameAccounts.ToArray(); }
            set
            {
                m_GameAccounts.Clear();
                m_GameAccounts.Add(value);
            }
        }

        [XmlIgnore]
        public GameAccountCollection GameAccountList
        {
            get { return m_GameAccounts; }
        }

        [XmlIgnore]
        public MatchContestant Team
        {
            get { return m_Team; }
            set { m_Team = value; }
        }

        [XmlIgnore]
        public int Kills
        {
            get
            {
                int kills = 0;
                foreach (MatchAction a in m_Actions)
                {
                    if (a.Action == MatchActions.Kills)
                        kills++;
                }
                return kills;
            }
        }

        [XmlIgnore]
        public int Headshots
        {
            get
            {
                int headshots = 0;
                foreach (MatchAction a in m_Actions)
                {
                    if (a.Action == MatchActions.Kills && (a.Flags & MatchActionFlags.Headshot) != 0)
                        headshots++;
                }
                return headshots;
            }
        }

        [XmlIgnore]
        public int Deaths
        {
            get
            {
                int deaths = 0;
                foreach (MatchAction a in m_Actions)
                {
                    if (a.Action == MatchActions.Dies)
                        deaths++;
                }
                return deaths;
            }
        }
        #endregion

        #region Methods     
        public void AddNick(string nick)
        {
            if (!m_Names.Contains(nick))
                m_Names.Add(nick);
        }

        public void AddNicks(string[] nicks)
        {
            foreach (string nick in nicks)
                AddNick(nick);
        }

        public void AddAction(MatchAction action)
        {
            m_Actions.Add(action);
        }

        public void AddActions(MatchAction[] actions)
        {
            m_Actions.AddRange(actions);
        }

        public void AddGameAccount(GameAccount account)
        {
            m_GameAccounts.Add(account);
        }

        public bool HasGameAccountWithID(string id)
        {
            foreach (GameAccount account in m_GameAccounts)
            {
                if (account.Value == id)
                    return true;
            }

            return false;
        }

        public bool HasNick(string nick)
        {
            if (m_Names.Contains(nick))
                return true;

            return false;
        }

        public void RemoveAction(MatchAction action)
        {
            if (m_Actions.Contains(action))
                m_Actions.Remove(action);
        }
        #endregion
    }
}
